/*
 * Chastoslov
 * Copyright (C) 2009 Alexandr Stroghov
 * 
 * stroghov@gmail.com
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the 
 * GNU General Public License, version 2, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program; if 
 * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 * MA 02111-1307 USA
*/
package world.ah.wf.guiclient;
import java.awt.Component;
import java.awt.Container;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.Properties;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import java.awt.BorderLayout;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JToolBar;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ActionMap;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.table.TableColumnModel;
import javax.swing.JComboBox;
import javax.swing.BorderFactory;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.awt.Color;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import java.awt.event.WindowEvent;
import java.awt.FlowLayout;
import java.awt.Insets;
import javax.swing.SwingConstants;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;

public class MainForm extends JFrame {
  private String prefFormHeader = "Chastoslov";
  private String prefWordsFound = "Words found: ";
  private String[] tableWordsColumnTitles = {"Word", "Frequency", "Checked"};
  private String anyTextLabel = "<any text>";
  private String noTextLabel = "<without text>";
  //
  private int savedTextId = -100;
  private int columnWordWidth = -1;
  private int columnCountWidth = -1;
  private int columnDoneWidth = -1;
  // 
  private ConnectionAssistant connAssist = new ConnectionAssistant() {
    public void connectedChanged(boolean connected) {
      connAssist_connectedChanged(connected);
    }
    public void readerNameChanged() {
      makeFormHeader();
    }
  };
  //
  CallableStatement statementsetWordDone;
  //
  DBTableModel tmWords = new DBTableModel(true) {
    public Object convertToShow(int column, Object value) {
      if(column == 2) return (Object)(new Boolean(((String)value).equalsIgnoreCase("Y")));
      else return value;
    }
    public Object convertToSave(int column, Object value) {
      if(column == 2) return (Object)(((Boolean)value).booleanValue() ? "Y" : "N");
      else return value;
    }
    //
    public DBPostResult postChanges (int column, Object [] record, Object newValue) {
      return tmWords_postChanges (column, record, newValue);
    }
  };
  // 
  private ImageIcon imageHelp = new ImageIcon(MainForm.class.getResource("help.gif"));
  private ImageIcon imageClose = new ImageIcon(MainForm.class.getResource("closefile.gif"));
  private ImageIcon imageOpen = new ImageIcon(MainForm.class.getResource("openfile.gif"));
  private ImageIcon imageConnect = new ImageIcon(MainForm.class.getResource("connect.gif"));
  private ImageIcon imageDisconnect = new ImageIcon(MainForm.class.getResource("disconnect.gif"));
  private ImageIcon imageRefresh = new ImageIcon(MainForm.class.getResource("refresh.gif"));
  private ImageIcon imageQuestion = new ImageIcon(MainForm.class.getResource("question.gif"));
  private JButton buttonHelp = new JButton();
  private JButton buttonClose = new JButton();
  private JButton buttonOpen = new JButton();
  private JToolBar toolBar = new JToolBar();
  private JLabel statusBar = new JLabel();
  private JMenuItem menuContent = new JMenuItem();
  private JMenu menuHelp = new JMenu();
  private JMenuItem menuExit = new JMenuItem();
  private JMenu menuFile = new JMenu();
  private JMenuBar menuBar = new JMenuBar();
  private JPanel panelCenter = new JPanel();
  private BorderLayout layoutMain = new BorderLayout();
  private JMenuItem menuConnect = new JMenuItem();
  private JMenuItem menuDisconnect = new JMenuItem();
  private JMenuItem menuConnParams = new JMenuItem();
  private JMenu menuData = new JMenu();
  private JMenu menuTools = new JMenu();
  private JMenuItem menuAbout = new JMenuItem();
  private JMenuItem menuOptions = new JMenuItem();
  private JMenuItem menuTexts = new JMenuItem();
  private JMenuItem menuLoadText = new JMenuItem();
  private JMenuItem menuDeleteText = new JMenuItem();
  
  private JMenuItem menuExportMarked = new JMenuItem();
  private JMenuItem menuImportMarked = new JMenuItem();
  
  private ActionMap actionMap1 = new ActionMap();
  private BorderLayout layoutCenter = new BorderLayout();
  private JPanel pFilters = new JPanel();
  private JPanel pTable = new JPanel();
  private JScrollPane spWords = new JScrollPane();
  private BorderLayout layoutTable = new BorderLayout();
  private JTable tWords = new JTable();
  private JPanel pStatusBar = new JPanel();
  private JLabel labWordsFound = new JLabel();
  private JButton bChangeConnected = new JButton();
  private ButtonGroup groupDone = new ButtonGroup();
  private FlowLayout layoutToolBar = new FlowLayout();
  private JLabel labText = new JLabel();
  private BorderLayout borderLayout5 = new BorderLayout();
  private JButton bRefreshTextList = new JButton();
  private BorderLayout borderLayout6 = new BorderLayout();
  private BorderLayout borderLayout7 = new BorderLayout();
  private JRadioButton radioDone = new JRadioButton();
  private JRadioButton radioNotDone = new JRadioButton();
  private JRadioButton radioAll = new JRadioButton();
  private JLabel labWord = new JLabel();
  private BorderLayout borderLayout8 = new BorderLayout();
  private BorderLayout borderLayout9 = new BorderLayout();
  private BorderLayout borderLayout11 = new BorderLayout();
  private JButton bRefresh = new JButton();
  private BorderLayout borderLayout12 = new BorderLayout();
  private JComboBox combText = new JComboBox();
  private BorderLayout borderLayout13 = new BorderLayout();
  private JTextField tfWord = new JTextField();
  private BorderLayout borderLayout14 = new BorderLayout();
  private JMenuItem menuUser = new JMenuItem();
  private GridBagLayout layoutFilter = new GridBagLayout();
  private JPanel pDone = new JPanel();
  private FlowLayout layoutDone = new FlowLayout();
  private JPanel pText = new JPanel();
  private GridBagLayout gridBagLayout2 = new GridBagLayout();
  private JPanel pWord = new JPanel();
  private GridBagLayout gridBagLayout1 = new GridBagLayout();
  private FlowLayout flowLayout1 = new FlowLayout();
  private FlowLayout layoutStatusBar = new FlowLayout();
  

  public MainForm() {
    try {jbInit();} catch(Exception e) {e.printStackTrace();}
    myInit();
  }
  
  // ИНИЦИАЛИЗАЦИЯ 
  private void jbInit() throws Exception {
    this.setJMenuBar(menuBar);
    this.getContentPane().setLayout(layoutMain);
    menuConnect.setText("Connect");
    menuConnect.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          bChangeConnected_actionPerformed(e);
        }
      });
    menuDisconnect.setText("Disconnect");
    menuDisconnect.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e) {
          bChangeConnected_actionPerformed(e);
        }
      });
    menuConnParams.setText("Connection properties");
    menuConnParams.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent ae) {
        menuConnectionParameters_ActionPerformed(ae);
      }
    });
    menuData.setText("Data");
    menuTools.setText("Tools");
    menuAbout.setText("About");
    menuAbout.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent ae)
        {
          helpAbout_ActionPerformed(ae);
        }
      });
    menuOptions.setText("Options");
    menuOptions.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuOptions_actionPerformed(e);
        }
      });
    menuTexts.setText("Texts");
    menuTexts.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuTexts_actionPerformed(e);
        }
      });
    menuLoadText.setText("Upload text");
    menuLoadText.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuLoadText_actionPerformed(e);
        }
      });
    menuDeleteText.setText("Delete text");
    menuDeleteText.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuDeleteText_actionPerformed(e);
        }
      });
      
      
    menuExportMarked.setText("Export checked words");
    menuExportMarked.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuExportMarked_actionPerformed(e);
        }
      });
      
    menuImportMarked.setText("Import checked words");
    menuImportMarked.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuImportMarked_actionPerformed(e);
        }
      });
      
      
      
    pFilters.setLayout(layoutFilter);
    pTable.setLayout(layoutTable);
    tWords.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
    tWords.setCellSelectionEnabled(true);
    pStatusBar.setLayout(layoutStatusBar);
    labWordsFound.setText("Words found: ");
    bChangeConnected.setIcon(imageConnect);
    bChangeConnected.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          bChangeConnected_actionPerformed(e);
        }
      });
    layoutToolBar.setAlignment(FlowLayout.LEFT);
    layoutToolBar.setHgap(0);
    layoutToolBar.setVgap(1);
    layoutDone.setAlignment(FlowLayout.CENTER);
    layoutDone.setHgap(10);
    layoutDone.setVgap(0);
    pText.setLayout(gridBagLayout2);
    pWord.setLayout(gridBagLayout1);
    layoutStatusBar.setAlignment(FlowLayout.LEADING);
    layoutStatusBar.setVgap(3);
    pDone.setLayout(layoutDone);
    labText.setText("Text");
    labText.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
    labText.setVerticalAlignment(SwingConstants.TOP);
    labText.setVerticalTextPosition(SwingConstants.TOP);
    labText.setOpaque(true);
    labText.setSize(new Dimension(50, 17));
    bRefreshTextList.setIcon(imageRefresh);
    bRefreshTextList.setMargin(new Insets(2, 2, 2, 2));
    bRefreshTextList.setSize(new Dimension(22, 22));
    bRefreshTextList.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          bPickFile_actionPerformed(e);
        }
      });
    borderLayout6.setHgap(5);
    radioDone.setText("Checked only");
    radioNotDone.setText("Unchecked only");
    radioNotDone.setSelected(true);
    radioAll.setText("All");
    labWord.setText("Word");
    labWord.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
    labWord.setVerticalAlignment(SwingConstants.TOP);
    borderLayout9.setHgap(7);
    bRefresh.setText("Refresh");
    bRefresh.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          bRefresh_actionPerformed(e);
        }
      });
    borderLayout12.setHgap(10);
    combText.setSize(new Dimension(355, 20));
    menuUser.setText("User");
    menuUser.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          menuUser_actionPerformed(e);
        }
      });
    this.setSize(new Dimension(414, 373));
    this.setTitle("Chastoslov");
    this.setForeground(Color.black);
    this.addWindowListener(new java.awt.event.WindowAdapter()
      {
        public void windowClosing(WindowEvent e)
        {
          this_windowClosing(e);
        }
      });
    this.addComponentListener(new java.awt.event.ComponentAdapter()
      {
        public void componentShown(ComponentEvent e)
        {
          this_componentShown(e);
        }

        public void componentResized(ComponentEvent e)
        {
          this_componentResized(e);
        }
      });
    menuFile.setText("Database");
    panelCenter.setLayout(layoutCenter);
    menuExit.setText("Exit");
    menuExit.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent ae)
        {
          fileExit_ActionPerformed(ae);
        }
      });
    menuHelp.setText("Help");
    menuContent.setText("Content");
    menuContent.setEnabled(false);
    statusBar.setText("");
    buttonOpen.setIcon(imageOpen);
    buttonOpen.setEnabled(false);
    toolBar.setLayout(layoutToolBar);
    toolBar.setBounds(new Rectangle(4, 0, 394, 33));
    buttonClose.setEnabled(false);
    buttonClose.setIcon(imageQuestion);
    buttonClose.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          buttonClose_actionPerformed(e);
        }
      });
    buttonHelp.setIcon(imageHelp);
    buttonHelp.setEnabled(false);
    menuFile.add(menuConnect);
    menuFile.add(menuDisconnect);
    menuFile.add(menuConnParams);
    menuFile.add(menuUser);
    menuFile.addSeparator();
    menuFile.add(menuExit);
    menuBar.add(menuFile);
    menuData.add(menuTexts);
    menuData.add(menuLoadText);
    menuData.add(menuDeleteText);
    menuData.add(menuExportMarked);
    menuData.add(menuImportMarked);
    menuBar.add(menuData);
    menuTools.add(menuOptions);
    menuBar.add(menuTools);
    menuHelp.add(menuAbout);
    menuHelp.addSeparator();
    menuHelp.add(menuContent);
    menuBar.add(menuHelp);
    this.getContentPane().add(statusBar, BorderLayout.WEST);
    toolBar.setFloatable(false);
    this.getContentPane().add(toolBar, BorderLayout.NORTH);
    toolBar.add(bChangeConnected, null);
    toolBar.add(buttonOpen, null);
    toolBar.add(buttonClose, null);
    toolBar.add(buttonHelp, null);
    spWords.getViewport().add(tWords, null);
    pTable.add(spWords, BorderLayout.CENTER);
    panelCenter.add(pTable, BorderLayout.CENTER);
    pText.add(labText, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 7, 0, 2), 0, 0));
    pText.add(combText, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 2), 0, 0));
    pText.add(bRefreshTextList, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 2, 0, 10), 0, 0));
    pDone.add(radioDone);
    pDone.add(radioNotDone);
    pDone.add(radioAll);
    pFilters.add(pDone, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 5, 10), 0, 0));
    pFilters.add(pText, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0));
    pWord.add(labWord, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 7, 0, 2), 0, 0));
    pWord.add(tfWord, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 5), 0, 0));
    pWord.add(bRefresh, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 0, 10), 0, 0));
    pFilters.add(pWord, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0));
    panelCenter.add(pFilters, BorderLayout.NORTH);
    pStatusBar.add(labWordsFound, null);
    panelCenter.add(pStatusBar, BorderLayout.SOUTH);
    this.getContentPane().add(panelCenter, BorderLayout.CENTER);
    
  }
  // МОЯ ИНИЦИАЛИЗАЦИЯ
  private void myInit() {
    groupDone.add(radioDone);
    groupDone.add(radioNotDone);
    groupDone.add(radioAll);
    tWords.getTableHeader().setReorderingAllowed(false);
    DBField [] dBFields = {
      new DBField("WORD", tableWordsColumnTitles[0], String.class, true),
      new DBField("COUNT", tableWordsColumnTitles[1], Integer.class, true),
      new DBField("DONE", tableWordsColumnTitles[2], Boolean.class, false)
    };
    tmWords.setDBFields(dBFields);
    tWords.setModel(tmWords);
    // Язык 
    setLang();
    //
    this.setTitle(prefFormHeader);
    this.connAssist_connectedChanged(false);
    // 
    if(WfGuiClient.connPropertiesFileName.length() > 0) 
      connAssist.setPropertiesFileName(WfGuiClient.connPropertiesFileName);
    else connAssist.setPropertiesFileName("wfConnection.properties");
    // Load form properties 
    Properties prop = new Properties();
    boolean propertiesLoaded = false;
    try {
      prop.load(new FileInputStream("wfMainForm.properties"));
      propertiesLoaded = true;
    } catch(Exception ex) {ErrorShower.show(null, "loading the form properties", "", ex);}
    if(propertiesLoaded) {
      // Set form properties
      Rectangle rect = new Rectangle();
      try {rect.x = Integer.parseInt(prop.getProperty("Left"));}
      catch (Exception ex) {rect.x = 100;}
      try {rect.y = Integer.parseInt(prop.getProperty("Top"));}
      catch (Exception ex) {rect.y = 200;}
      try {rect.width = Integer.parseInt(prop.getProperty("Width"));}
      catch (Exception ex) {rect.width = 400;}
      try {rect.height = Integer.parseInt(prop.getProperty("Height"));}
      catch (Exception ex) {rect.height = 400;}
      this.setBounds(rect);
      //
      int i;
      try {savedTextId = Integer.parseInt(prop.getProperty("FilterTextId"));} 
      catch (Exception ex) {}
      //
      try {columnWordWidth = Integer.parseInt(prop.getProperty("columnWordWidth"));} 
      catch (Exception ex) {}
      try {columnCountWidth = Integer.parseInt(prop.getProperty("columnCountWidth"));} 
      catch (Exception ex) {}
      try {columnDoneWidth = Integer.parseInt(prop.getProperty("columnDoneWidth"));} 
      catch (Exception ex) {}
    }
    // Load connection properties
    try {
    connAssist.loadProperties(); 
    } catch (Exception ex) {
      ErrorShower.show(this, "loading connection properties", "", ex);
    }
  }
  
  /** Устанавливает язык интерфейса */
  public void setLang() {
    String s;
    prefFormHeader = General.getLangItem("ProgramTitle", "Chastoslov");
    makeFormHeader();
    s = General.getLangItem("Database"); if(s.length() > 0) menuFile.setText(s);
    s = General.getLangItem("Connect"); if(s.length() > 0) menuConnect.setText(s);
    s = General.getLangItem("Disconnect"); if(s.length() > 0) menuDisconnect.setText(s);
    s = General.getLangItem("ConnectionParameters"); if(s.length() > 0) menuConnParams.setText(s);
    s = General.getLangItem("User"); if(s.length() > 0) menuUser.setText(s);
    s = General.getLangItem("Exit"); if(s.length() > 0) menuExit.setText(s);
    s = General.getLangItem("Data"); if(s.length() > 0) menuData.setText(s);
    s = General.getLangItem("mTools"); if(s.length() > 0) menuTools.setText(s);
    s = General.getLangItem("mAbout"); if(s.length() > 0) menuAbout.setText(s);
    s = General.getLangItem("Options"); if(s.length() > 0) menuOptions.setText(s);
    s = General.getLangItem("Texts"); if(s.length() > 0) menuTexts.setText(s);
    s = General.getLangItem("UploadText"); if(s.length() > 0) menuLoadText.setText(s);
    s = General.getLangItem("DeleteText"); if(s.length() > 0) menuDeleteText.setText(s);
    s = General.getLangItem("ExportMarkedWords"); if(s.length() > 0) menuExportMarked.setText(s);
    s = General.getLangItem("ImportMarkedWords"); if(s.length() > 0) menuImportMarked.setText(s);
    s = General.getLangItem("mHelp"); if(s.length() > 0) menuHelp.setText(s);
    s = General.getLangItem("mContent"); if(s.length() > 0) menuContent.setText(s);
    s = General.getLangItem("Text"); if(s.length() > 0) labText.setText(s);
    s = General.getLangItem("DoneOnly"); if(s.length() > 0) radioDone.setText(s);
    s = General.getLangItem("NotDoneOnly"); if(s.length() > 0) radioNotDone.setText(s);
    s = General.getLangItem("All"); if(s.length() > 0) radioAll.setText(s);
    s = General.getLangItem("Word"); if(s.length() > 0) labWord.setText(s); 
    s = General.getLangItem("Refresh"); if(s.length() > 0) bRefresh.setText(s);
    tmWords.getDBFields()[0].setTitle(General.getLangItem("Word", tableWordsColumnTitles[0]));
    tmWords.getDBFields()[1].setTitle(General.getLangItem("Frequency", tableWordsColumnTitles[1]));
    tmWords.getDBFields()[2].setTitle(General.getLangItem("Done", tableWordsColumnTitles[2]));
    prefWordsFound = General.getLangItem("WordsFound", "Words found") + ": ";
    makeWordsFound();
    s = General.getLangItem("anyTextLabel"); if(s.length() > 0) anyTextLabel = s;
    s = General.getLangItem("noTextLabel"); if(s.length() > 0) noTextLabel = s;
  }

  void menuConnectionParameters_ActionPerformed(ActionEvent e) {
    DialogConnProperties fr = new DialogConnProperties(this, "", true);
    fr.setConnAssist(connAssist);
    fr.setVisible(true);
  }

  void fileExit_ActionPerformed(ActionEvent e) {
    System.exit(0);
  }

  void helpAbout_ActionPerformed(ActionEvent e) {
    JOptionPane.showMessageDialog(this, new Main_AboutBoxPanel1(), General.getLangItem("mAbout", 
      "About"), JOptionPane.PLAIN_MESSAGE);
  }

  private void tryToConnect() {
    boolean problem = false;
    if(connAssist.getRememberPassword()) {
      try {connAssist.connect();}
      catch(Exception ex) {ErrorShower.show(this, "connect", "", ex); problem = true;};
    } else menuConnectionParameters_ActionPerformed(null);
    //
    if(problem) menuConnectionParameters_ActionPerformed(null);
  }

  private void this_componentShown(ComponentEvent e) {
    if(connAssist.getAutoConnect()) tryToConnect();
  }
  //
  private void makeWordsFound() {
    int wordsFound = tmWords.getRowCount();
    if(wordsFound > 0) labWordsFound.setText(prefWordsFound + Integer.toString(wordsFound));
    else labWordsFound.setText(prefWordsFound);
  }
  // Очистить или вывести список слов 
  private void processWords(boolean show) {
    if(show) {
      try {
        int textIdPos = 0, donePos = 0, wordPos = 0, i = 0;
        int textId = ((KeyedItem)(combText.getSelectedItem())).getKey();
        String sql = "select WORD_ID, WORD, COUNT, DONE from ";
        if(textId > 0) sql += "WORDS_BY_TEXTS ";
        else sql += "ALL_WORDS ";
        sql += "where 1=1 ";
        if(textId > 0) {sql += "and TEXT_ID = ? "; i++; textIdPos = i;}
        if(!radioAll.isSelected()) {sql += "and DONE = ? "; i++; donePos = i;}
        if(tfWord.getText().length() > 0) {sql += "and WORD like ? escape '_' "; i++; wordPos = i;}
        if(textId == 0) sql += "and COUNT is null ";
        sql += "order by case when COUNT is null then 0 else count end desc, WORD asc ";
        //System.out.println(sql);
        //
        PreparedStatement st = 
          connAssist.getConn().prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, 
          ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); 
        if(textIdPos > 0) st.setInt(textIdPos, textId);
        if(donePos > 0) st.setString(donePos, radioDone.isSelected() ? "Y" : "N");
        if(wordPos > 0) st.setString(wordPos, "%" +
          tfWord.getText().replaceAll("_", "__").replaceAll("%", "_%").toLowerCase() + "%");
        //
        ResultSet rs = st.executeQuery();
        tmWords.setDataSource(rs);
        rs.close();
      } catch (Exception ex) {
        ErrorShower.show(this, "showing word list", "", ex);
      }
      TableColumnModel cols = tWords.getTableHeader().getColumnModel();
      if(columnWordWidth >= 0) cols.getColumn(0).setPreferredWidth(columnWordWidth);
      if(columnCountWidth >= 0) cols.getColumn(1).setPreferredWidth(columnCountWidth);
      if(columnDoneWidth >= 0) cols.getColumn(2).setPreferredWidth(columnDoneWidth);
    } else {
      TableColumnModel cols = tWords.getTableHeader().getColumnModel();
      if(cols.getColumnCount() > 0) {
        columnWordWidth = cols.getColumn(0).getWidth();
        columnCountWidth = cols.getColumn(1).getWidth();
        columnDoneWidth = cols.getColumn(2).getWidth();
        //System.out.println(Integer.toString(columnWordWidth) + " - " + 
        //Integer.toString(columnCountWidth) + " - " + Integer.toString(columnDoneWidth)
        //);
      }
      try {tmWords.setDataSource(null);} 
      catch (Exception ex) {ErrorShower.show(this, "clearing word list", "", ex);
      }
    }
    makeWordsFound();
  }
  // Активация/деактивация всех компонентов контейнера рекурсивно
  private void setRecursiveEnabled(Container cont, boolean enable) {
    Component[] comps = cont.getComponents();
    for(int i = 0; i < comps.length; i++) 
      if(comps[i] instanceof Container) setRecursiveEnabled((Container)comps[i], enable);
      else comps[i].setEnabled(enable);
    cont.setEnabled(enable);
  }
  // Заполнить список текстов 
  private void fillTextList() {
    String sql = "select ID, TITLE from TEXT order by TITLE asc";
    //System.out.println(sql);
    int indexTorestore = -100;
    try {
      Statement st = connAssist.getConn().createStatement(ResultSet.TYPE_FORWARD_ONLY, 
        ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
      ResultSet rs = st.executeQuery(sql);
      // Заполняем постоянные элементы 
      combText.addItem(new KeyedItem(-1, anyTextLabel));
      if(savedTextId == -1) indexTorestore = combText.getItemCount() - 1;
      combText.addItem(new KeyedItem(0, noTextLabel));
      if(savedTextId == 0) indexTorestore = combText.getItemCount() - 1;
      // Заполняем из элементы БД
      while(rs.next()) {
        combText.addItem(new KeyedItem(rs.getInt(1), rs.getString(2)));
        if(rs.getInt(1) == savedTextId) indexTorestore = combText.getItemCount() - 1;
      };
      rs.close();
    } catch (Exception ex) {ErrorShower.show(this, "filling of text list", "", ex);}
    if(indexTorestore >= 0) combText.setSelectedIndex(indexTorestore); 
  }
  // Oчистить список текстов 
  private void clearTextList() {
    if(combText.getItemCount() > 0) 
      savedTextId = ((KeyedItem)(combText.getSelectedItem())).getKey();
    combText.removeAllItems();
  }
  //
  private void makeFormHeader(String readerName) {
    if(readerName == null || readerName.length() < 1) setTitle(prefFormHeader);
    else this.setTitle(prefFormHeader + " - " + readerName);
  }
  //
  private void makeFormHeader() {
    String newReaderName = connAssist.getReaderName();
    if(connAssist.getConnected()) 
      if(newReaderName == null || newReaderName.length() < 1) setTitle(prefFormHeader + " - <" +  
        connAssist.getUserName() + ">");
      else this.setTitle(prefFormHeader + " - " + newReaderName);
    else this.setTitle(prefFormHeader);
  }
  /**
   * Приведение внешнего вида окна в соответствие с сотоянием подключения
   * @param connected состояние подключение (подключено/отключено)
   */
  private void connAssist_connectedChanged(boolean connected) {
    menuTexts.setEnabled(connected);
    menuLoadText.setEnabled(connected);
    menuDeleteText.setEnabled(connected);
    menuConnect.setEnabled(!connected);
    menuDisconnect.setEnabled(connected);
    menuUser.setEnabled(connected);
    setRecursiveEnabled(pFilters, connected);
    //
    if(connected) {
      bChangeConnected.setIcon(imageDisconnect);
      // Готовим оператор для пометки слов
      try {statementsetWordDone = connAssist.getConn().prepareCall("{call SET_WORD_DONE(?, ?)}");
      } catch(Exception ex) {ErrorShower.show(this, "prepare statement to mark", "", ex);}
      fillTextList();
      processWords(true);
    } else {
      bChangeConnected.setIcon(imageConnect);
      clearTextList();
      processWords(false);
    };
    makeFormHeader();
  }
  //
  private DBPostResult tmWords_postChanges (int column, Object [] record, Object newValue) {
    DBPostResult result = new DBPostResult(false, null);
    try {
      if(column == 2) {
        statementsetWordDone.setInt(1, ((Integer)record[0]).intValue());
        String done = ((Boolean)newValue).booleanValue() ? "Y" : "N";
        statementsetWordDone.setString(2, done);
        statementsetWordDone.executeUpdate();
        result.setSucceed(true);
      }
    } catch (Exception ex) {
      ErrorShower.show(this, "posting data", "", ex); 
      result.setSucceed(false);
    }
    return result;
  }
  //
  private void bChangeConnected_actionPerformed(ActionEvent e) {
    if(connAssist.getConnected()) {
      try {
        connAssist.disconnect();
      } catch(Exception ex) {ErrorShower.show(this, "disconnect", "", ex);};
    } else {
      tryToConnect();
    }
  }

  private void bRefresh_actionPerformed(ActionEvent e) {
    processWords(false);
    processWords(true);
  }

  private void this_windowClosing(WindowEvent e) {
    // Disconnect
    try {connAssist.disconnect();}
    catch(Exception ex) {ErrorShower.show(this, "disconnect", "", ex);};
    // Save form properties
    Properties prop = new Properties();
    prop.setProperty("Left", Integer.toString(this.getBounds().x));
    prop.setProperty("Top", Integer.toString(this.getBounds().y));
    prop.setProperty("Width", Integer.toString(this.getBounds().width));
    prop.setProperty("Height", Integer.toString(this.getBounds().height));
    //
    prop.setProperty("FilterTextId", Integer.toString(savedTextId));
    //
    prop.setProperty("columnWordWidth", Integer.toString(this.columnWordWidth));
    prop.setProperty("columnCountWidth", Integer.toString(this.columnCountWidth));
    prop.setProperty("columnDoneWidth", Integer.toString(this.columnDoneWidth));
    try {
      prop.store(new FileOutputStream("wfMainForm.properties"), "Main form parameters");
    } catch (Exception ex) {
      ErrorShower.show(this, "saving the form properties", "", ex);
    }
    // Save connection properties
    try {
    connAssist.saveProperties(); 
    } catch (Exception ex) {
      ErrorShower.show(this, "saving connection properties", "", ex);
    }
    // Save program options
    try {General.optionsHolder.saveProperties();} 
    catch (Exception ex) {ErrorShower.show(this, "saving program options", "", ex);}
    //
  }

  private void menuLoadText_actionPerformed(ActionEvent e) {
    DialogUploadText fr = new DialogUploadText(this, "", true);
    fr.setConn(connAssist.getConn());
    fr.setVisible(true);
  }

  private void buttonClose_actionPerformed(ActionEvent e) {
    int a = 9;
    int ii = a / 2;
    System.out.println(Integer.toString(ii));
    
    try {
      throw new Exception("Сообщение с очень очень очень очень очень очень очень очень очень " + 
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " + 
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " +
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " +
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " +
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " +
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " + 
      "очень очень очень очень очень очень очень очень очень очень очень очень очень очень очень " + 
      "длинным текстом!");
      
    } catch (Exception ex) {ErrorShower.show(this, "тест", "", ex);}
    //

    
    StringTable st = new StringTable(3);
    /*st.add(); st.set(0, "English"); st.set(1, "English"); st.set(2, "langEnglish.properties");
    st.add(); st.set(0, "Russian"); st.set(1, "Русский(\"родной\")"); st.set(2, "langRussian.properties");
    try {
      st.store(new FileOutputStream("wfLanguages.properties"));
    } catch (Exception ex) {ErrorShower.show(this, "тест", "", ex);} 
    */
    
    st.clear();
    try {
      st.load(new FileInputStream("wfLanguages.properties"));
    } catch (Exception ex) {ErrorShower.show(this, "тест", "", ex);}     
    //st.reset();
    System.out.println("-----------------");
    //while(st.next()) {
    for(int r = 0; r < st.getRowCount(); r++) {
      for(int i = 0; i < 3; i++) {
        //String s;
        //try {s = st.get(r, i);} catch (Exception ex) {s = ex.getMessage();};
        System.out.println(st.get(r, i));
      }
      System.out.println("-----------------");
    }
    
  
  }

  private void menuDeleteText_actionPerformed(ActionEvent e) {
    DialogDeleteText fr = new DialogDeleteText(this, "", true);
    fr.setConn(connAssist.getConn());
    fr.setVisible(true);
  }

  private void menuExportMarked_actionPerformed(ActionEvent e) {
    DialogExportMarked fr = new DialogExportMarked(this, "", true);
    fr.setConn(connAssist.getConn());
    fr.setVisible(true);
  }

  private void menuImportMarked_actionPerformed(ActionEvent e) {
    DialogImportMarked fr = new DialogImportMarked(this, "", true);
    fr.setConn(connAssist.getConn());
    fr.setVisible(true);
  }

  private void menuTexts_actionPerformed(ActionEvent e) {
    DialogTexts fr = new DialogTexts(this, "", true);
    fr.setConn(connAssist.getConn());
    fr.setVisible(true);
  }

  private void this_componentResized(ComponentEvent e) {
    General.controlMinimumSize(this, 400, 400);
  }

  private void bPickFile_actionPerformed(ActionEvent e) {
    this.clearTextList();
    this.fillTextList();
  }

  private void menuOptions_actionPerformed(ActionEvent e) {
    DialogOptions fr = new DialogOptions(this, "", true);
    fr.setVisible(true);
  }

  private void menuUser_actionPerformed(ActionEvent e) {
    DialogUser fr = new DialogUser(this, "", true);
    fr.setConnAssist(connAssist);
    fr.setVisible(true);
  }
  
  
  
}
